﻿using RotovapPlatform.Domain.Business.Machine.Enums;
using RotovapPlatform.Domain.Business.Recipes.Entities;
using RotovapPlatform.Domain.Common;
using RotovapPlatform.Domain.Services.Experiments;
using System;
using System.Threading.Tasks;
using static RotovapPlatform.Domain.Business.Machine.Enums.ExperimentConfigEnums;

namespace RotovapPlatform.Application.Services.Experiments
{
	/// <summary>
	/// 实验流程应用服务接口
	/// 负责实验组配方验证成功后，货位分配完成后进行具体的旋蒸实验
	/// 包含各种旋蒸的大步骤：搬运、加热、旋蒸、收集、清洗等
	/// </summary>
	public interface IExperimentProcessAppService : IDisposable
	{
		/// <summary>
		/// 当前实验阶段变更事件
		/// </summary>
		event EventHandler<ExperimentStageChangedEventArgs> ExperimentStageChanged;

		/// <summary>
		/// 当前实验子阶段变更事件
		/// </summary>
		event EventHandler<ExperimentSubStageChangedEventArgs> ExperimentSubStageChanged;

		/// <summary>
		/// 获取当前实验ID
		/// </summary>
		Guid? CurrentExperimentId { get; }

		/// <summary>
		/// 获取当前实验阶段
		/// </summary>
		ExperimentStage? CurrentStage { get; }

		/// <summary>
		/// 获取当前实验子阶段
		/// </summary>
		ExperimentSubStage? CurrentSubStage { get; }

		/// <summary>
		/// 执行物料&条件准备阶段
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteMaterialAndConditionPreparationAsync(Guid experimentId);

		/// <summary>
		/// 执行旋蒸阶段
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteRotaryEvaporationAsync(Guid experimentId);

		/// <summary>
		/// 执行旋蒸残液处理阶段
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteEvaporationResidueProcessingAsync(Guid experimentId);

		/// <summary>
		/// 执行冷凝液处理阶段
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteCondensateProcessingAsync(Guid experimentId);

		/// <summary>
		/// 执行清洗阶段
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteCleaningAsync(Guid experimentId);

		/// <summary>
		/// 执行整个实验
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>实验对象</returns>
		Task<Experiment> ExecuteExperimentAsync(Guid experimentId);

		/// <summary>
		/// 获取实验状态
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>实验对象</returns>
		Task<Experiment> GetExperimentStatusAsync(Guid experimentId);

		/// <summary>
		/// 获取实验组状态
		/// </summary>
		/// <param name="experimentGroupId">实验组ID</param>
		/// <returns>实验组对象</returns>
		Task<ExperimentGroup> GetExperimentGroupStatusAsync(Guid experimentGroupId);

		/// <summary>
		/// 获取实验参数
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <returns>实验对象</returns>
		Task<Experiment> GetExperimentParametersAsync(Guid experimentId);

		/// <summary>
		/// 获取设备状态
		/// </summary>
		/// <returns>设备状态信息</returns>
		Task<DeviceStatusInfo> GetDeviceStatusAsync();

		/// <summary>
		/// 手动扫描物料条码
		/// </summary>
		/// <returns>操作结果，包含条码数据</returns>
		Task<OperationResult<string>> ManualScanMaterialBarcodeAsync();

		/// <summary>
		/// 手动验证物料
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <param name="barcodeData">条码数据</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ManualValidateMaterialAsync(Guid experimentId, string barcodeData);

		/// <summary>
		/// 手动放置物料
		/// </summary>
		/// <param name="experimentId">实验ID</param>
		/// <param name="materialId">物料ID</param>
		/// <param name="position">位置</param>
		/// <returns>操作结果</returns>
		Task<OperationResult> ManualPlaceMaterialAsync(Guid experimentId, Guid materialId, string position);

		/// <summary>
		/// 手动执行紧急停止
		/// </summary>
		/// <returns>操作结果</returns>
		Task<OperationResult> ExecuteEmergencyStopAsync();

		/// <summary>
		/// 手动重置设备
		/// </summary>
		/// <returns>操作结果</returns>
		Task<OperationResult> ResetDeviceAsync();

		/// <summary>
		/// 获取机械手状态
		/// </summary>
		/// <returns>机械手状态</returns>
		Task<RobotArmState> GetRobotArmStateAsync();

		/// <summary>
		/// 执行设备初始化
		/// </summary>
		/// <returns>操作结果</returns>
		Task<OperationResult> InitializeDevicesAsync();
	}

	/// <summary>
	/// 设备状态信息
	/// </summary>
	public class DeviceStatusInfo
	{
		/// <summary>
		/// 设备模式
		/// </summary>
		public DeviceEnums.DeviceMode DeviceMode { get; set; }

		/// <summary>
		/// 设备状态
		/// </summary>
		public DeviceEnums.DeviceStatus DeviceStatus { get; set; }

		/// <summary>
		/// 油浴温度
		/// </summary>
		public double OilBathTemperature { get; set; }

		/// <summary>
		/// 冷凝温度
		/// </summary>
		public double CondensationTemperature { get; set; }

		/// <summary>
		/// 旋转速度
		/// </summary>
		public double RotationSpeed { get; set; }

		/// <summary>
		/// 真空度
		/// </summary>
		public double Vacuum { get; set; }

		/// <summary>
		/// 机械臂状态
		/// </summary>
		public RobotArmState RobotArmStatus { get; set; }

		/// <summary>
		/// 机械臂位置
		/// </summary>
		public string RobotArmPosition { get; set; }

		/// <summary>
		/// 错误代码
		/// </summary>
		public int ErrorCode { get; set; }

		/// <summary>
		/// 错误信息
		/// </summary>
		public string ErrorMessage { get; set; }
	}
}